package com.example.wacoffee_user.aspect;


import com.example.wacoffee_user.annotation.AutoFill;
import com.example.wacoffee_user.common.AutoFillConstant;
import com.example.wacoffee_user.common.OperationType;
import com.example.wacoffee_user.utils.CurrentHoler;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Aspect
@Component
@Slf4j
public class AutoFillAspect {
 @Pointcut("execution(* com.example.wacoffee_user.mapper.*.*(..)) && @annotation(com.example.wacoffee_user.annotation.AutoFill)")
    public void autoFillPointCut() {}
 @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint){
        log.info("开始进行公共字段填充");
     MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
     AutoFill autoFill = methodSignature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
     OperationType operationType = autoFill.value();
     Object[] args= joinPoint.getArgs();
     if(args==null||args.length==0)return ;
     Object entity=args[0];
     LocalDateTime now=LocalDateTime.now();

     if(operationType==OperationType.INSERT){
         try {
             //获取实体对象的set方法
             //entity.getClass().getDeclaredMethod(方法名，方法参数)
             //entity是Object类型，没有getset方法，必须通过反射获得方法
             //为什么是AutoFillConstant，而不是直接是"setCreateTime"：因为不想把代码写死，所以用常量类封装
             Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
             Method setCreator = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
             Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
             Method setUpdater = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
             Long id= CurrentHoler.getCurrentId().longValue();
            // Long id=1L;
             //通过反射为对象属性赋值
             setCreateTime.invoke(entity,now);
             setCreator.invoke(entity,id);
             setUpdateTime.invoke(entity,now);
             setUpdater.invoke(entity,id);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }else if(operationType == OperationType.UPDATE){
         Long id= CurrentHoler.getCurrentId().longValue();
         //为2个公共字段赋值
         try {
             Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
             Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

             //通过反射为对象属性赋值
             setUpdateTime.invoke(entity,now);
             setUpdateUser.invoke(entity,id);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 }
}
